Skip to content

fix(link-previews): proxy sent preview media - #5627

Merged
wesbillman merged 1 commit into
mainfrom
tho/link-preview-media-proxy
Aug 12, 2026
Merged

fix(link-previews): proxy sent preview media#5627
wesbillman merged 1 commit into
mainfrom
tho/link-preview-media-proxy

Conversation

@tellaho

@tellaho tellaho commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Overview

Category: fix
User Impact: Sent link previews now reliably display their thumbnail and favicon when the media is hosted on the relay.

Problem: Sent preview cards loaded relay-hosted snapshot media directly, so authenticated relay requests could fail even though the snapshot itself was valid. Solution: Rewrite snapshot media at the shared card render boundary through Buzz's authenticated local media proxy, preserving the original display domain and rerendering when the proxy becomes ready.

Changes

File changes

desktop/src/shared/ui/link-preview-attachment.tsx
Routes sent preview thumbnails and favicons through authenticated relay media handling above the Compact/Rich fork while preserving original metadata.

desktop/src/testing/e2eBridge.ts
Adds an opt-in proxy-readiness seam that deterministically re-arms the production media lookup when released.

desktop/tests/e2e/messaging.spec.ts
Covers the real send, snapshot, recipient, and card-render path for Compact and Rich previews, including fallback URLs, proxied URLs, and decoded image content.

desktop/tests/helpers/bridge.ts
Exposes the opt-in media-proxy startup state to E2E tests.

Reproduction Steps

  1. Send a link whose preview snapshot includes a relay-hosted thumbnail and favicon.
  2. Inspect the sent message card in Compact mode and confirm both images render after the local media proxy becomes ready.
  3. Switch link previews to Rich mode and confirm the thumbnail and favicon continue to render.
  4. Run the focused Playwright regression:
    pnpm exec playwright test tests/e2e/messaging.spec.ts --project=smoke --grep "sent link preview media uses the authenticated proxy"

Before / After

Before After
Relay-hosted preview media fails to load. The sent preview thumbnail and favicon render through the authenticated media proxy.
Before: sent link preview with a missing thumbnail After: sent link preview with the thumbnail rendered

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
@tellaho
tellaho marked this pull request as ready for review August 12, 2026 04:39
@tellaho
tellaho requested a review from a team as a code owner August 12, 2026 04:39

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed on Wes’s behalf at exact head 48eccf547e2358f9f97b4b4e7453bb2af0b86dbf. No actionable findings from my pass. The render-boundary rewrite is correctly shared by Compact and Rich cards, preserves the original imageDomain, leaves data/external URLs unchanged, and subscribes to proxy-port publication so initial buzz-media:// fallbacks are replaced without requiring unrelated state changes. Snapshot parsing already restricts authored media to exact active-relay /media/<sha>.<image-ext> URLs tied to message content, so this does not widen the proxy trust boundary. I also traced cache reset/community-switch behavior: the existing generation guard prevents stale origin/port publication, and useMediaProxyPort rerenders on both cleared and newly resolved ports. The new E2E exercises send → uploaded snapshot → recipient parse → Compact render, delayed proxy readiness, decoded image content, and Rich rerender. git diff --check origin/main...48eccf547e2358f9f97b4b4e7453bb2af0b86dbf passes; current GitHub CI is fully green and the head is mergeable. Per policy, this is findings-only, not an approval.

@wesbillman wesbillman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adversarial review at exact head 48eccf547e2358f9f97b4b4e7453bb2af0b86dbf: no actionable findings.

I traced the complete path rather than only the new E2E:

  • Recipient-side external cards come exclusively from validated sender snapshot tags (parseLinkPreviewSnapshots), whose media pairs are constrained to the active relay origin and matching 64-hex path/hash. This means the new render-boundary rewrite receives the relay-owned URLs it is intended to proxy, not arbitrary external image URLs.
  • LinkPreviewAttachment rewrites both favicon and image before the Compact/Rich fork, so every sent-card shape receives the same treatment while the original imageDomain remains intact for display/alt metadata.
  • The useMediaProxyPort subscription closes the cold-start race: initial rendering may use the buzz-media:// fallback, and the component rerenders when fetchProxyPort publishes a nonzero port. Existing cache-generation guards prevent a lookup from a previous community from repopulating the cache after reset.
  • rewriteRelayUrl still passes external Blossom media through once the relay origin is known, and snapshot parsing independently rejects non-relay media for this path.
  • The E2E exercises the actual compose → upload → signed snapshot → recipient parse → Compact render flow, then releases proxy readiness and verifies both URL transition and decoded image content before switching to Rich and checking both media elements again.

I also checked failure-state behavior: the child components key image failures by the current rewritten URL, so an initial fallback/proxy failure does not permanently poison a later URL transition.

git diff --check origin/main...HEAD passes on a clean detached worktree. GitHub reports the exact head mergeable with all applicable checks terminal and green. I did not duplicate CI-equivalent suites locally.

@wesbillman
wesbillman merged commit 884ed8a into main Aug 12, 2026
26 checks passed
@wesbillman
wesbillman deleted the tho/link-preview-media-proxy branch August 12, 2026 17:24
wpfleger96 added a commit that referenced this pull request Aug 12, 2026
Ready-for-review prep for the model-capabilities manifest PR:
- Merge origin/main (15 commits) into the branch. The one changed-in-both
  file, UserProfilePopover.tsx, auto-merged cleanly: main's #5574 extracted
  interaction handlers into useProfileInteractionActions (disjoint region),
  leaving the managedAgent.model label render path untouched, so the
  resolveModelLabel rewire survives with identical semantics.
- Re-point scripts/normative-corpus.json:562 _note from the deleted
  DATABRICKS_V2_OPENAI_CODE_NAMES constant to the manifest mechanism that
  now owns the behavior (boundary-aligned family_tokens + databricks_v2
  concrete-unknown fallback). Doc-only; every expect block byte-identical.

* origin/main:
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)
  Refine channel settings and profile panels (#5574)
  fix(deps): bump webbrowser to 1.2.4 for RUSTSEC-2026-0257 (#5659)
  feat(acp): deliver channel description in prompt [Context] (#4552)
  fix(desktop): launch Databricks OAuth from passive model discovery (#5607)
  chore(release): release Buzz Desktop version 0.5.10 (#5613)
  fix(desktop): remove 0.5.9+ perf regressions, speed up get_channels (#5599)
  perf(desktop): coalesce read state localStorage persistence (#5591)
  fix(relay): stop panicking the ingest worker on reactions to project events (#5294)
  fix(desktop): bound initial timeline retention (#5603)
  fix(relay): log event kind on the HTTP bridge /events line (#5291)
  feat(tracing): add PostgreSQL tracing spans (#3678)

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
bradseiler pushed a commit that referenced this pull request Aug 12, 2026
…igration

* origin/main:
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)
  Refine channel settings and profile panels (#5574)
  fix(deps): bump webbrowser to 1.2.4 for RUSTSEC-2026-0257 (#5659)
  feat(acp): deliver channel description in prompt [Context] (#4552)
  fix(desktop): launch Databricks OAuth from passive model discovery (#5607)

Co-authored-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>
Signed-off-by: coder 0 <d97ebdbb198c7237c94f84ea8bb8a73583ea067407eebd0062abbb3962527fb1@buzz.block.builderlab.xyz>

# Conflicts:
#	crates/buzz-media/src/lib.rs
#	crates/buzz-media/src/storage.rs
morgmart added a commit that referenced this pull request Aug 13, 2026
…graphy-staging

* origin/main:
  Harden shared agent instruction review (#4220)
  chore(release): release Buzz Desktop version 0.5.11 (#5714)
  feat(acp): report standard adapter usage (#4950)
  fix(mobile): settle hydrated threads on latest reply (#4702)
  perf(desktop): persist channel snapshot hash (#5684)
  fix(agent): raise output limit and allow 3 recoveries (#5475)
  fix(desktop): defer foreground resume work (#5696)
  perf(desktop): coalesce thread-activity localStorage writes (#5693)
  Batch observer-store publications per relay envelope (#5680)
  feat(buzz-acp): idle re-sleep for woken lazy pools (#5682)
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)
  Refine channel settings and profile panels (#5574)
  fix(deps): bump webbrowser to 1.2.4 for RUSTSEC-2026-0257 (#5659)
  feat(acp): deliver channel description in prompt [Context] (#4552)
  fix(desktop): launch Databricks OAuth from passive model discovery (#5607)

Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
tlongwell-block pushed a commit that referenced this pull request Aug 13, 2026
…ent-config

* origin/main: (31 commits)
  Harden shared agent instruction review (#4220)
  chore(release): release Buzz Desktop version 0.5.11 (#5714)
  feat(acp): report standard adapter usage (#4950)
  fix(mobile): settle hydrated threads on latest reply (#4702)
  perf(desktop): persist channel snapshot hash (#5684)
  fix(agent): raise output limit and allow 3 recoveries (#5475)
  fix(desktop): defer foreground resume work (#5696)
  perf(desktop): coalesce thread-activity localStorage writes (#5693)
  Batch observer-store publications per relay envelope (#5680)
  feat(buzz-acp): idle re-sleep for woken lazy pools (#5682)
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)
  Refine channel settings and profile panels (#5574)
  fix(deps): bump webbrowser to 1.2.4 for RUSTSEC-2026-0257 (#5659)
  feat(acp): deliver channel description in prompt [Context] (#4552)
  fix(desktop): launch Databricks OAuth from passive model discovery (#5607)
  chore(release): release Buzz Desktop version 0.5.10 (#5613)
  fix(desktop): remove 0.5.9+ perf regressions, speed up get_channels (#5599)
  ...

Co-authored-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>
Signed-off-by: Eva <011987e296fd5006292d2f930b574be47c7801048d1983c46c425d3c95f0cffd@buzz.block.builderlab.xyz>

# Conflicts:
#	desktop/src-tauri/src/commands/personas/inbound.rs
#	desktop/src-tauri/src/commands/personas/inbound/inbound_tests.rs
wpfleger96 added a commit that referenced this pull request Aug 13, 2026
* origin/main:
  Harden shared agent instruction review (#4220)
  chore(release): release Buzz Desktop version 0.5.11 (#5714)
  feat(acp): report standard adapter usage (#4950)
  fix(mobile): settle hydrated threads on latest reply (#4702)
  perf(desktop): persist channel snapshot hash (#5684)
  fix(agent): raise output limit and allow 3 recoveries (#5475)
  fix(desktop): defer foreground resume work (#5696)
  perf(desktop): coalesce thread-activity localStorage writes (#5693)
  Batch observer-store publications per relay envelope (#5680)
  feat(buzz-acp): idle re-sleep for woken lazy pools (#5682)
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)

Signed-off-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz>
Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
cameronhotchkies pushed a commit that referenced this pull request Aug 13, 2026
…read-context

* origin/main: (38 commits)
  Add mobile community invites (#5641)
  Harden shared agent instruction review (#4220)
  chore(release): release Buzz Desktop version 0.5.11 (#5714)
  feat(acp): report standard adapter usage (#4950)
  fix(mobile): settle hydrated threads on latest reply (#4702)
  perf(desktop): persist channel snapshot hash (#5684)
  fix(agent): raise output limit and allow 3 recoveries (#5475)
  fix(desktop): defer foreground resume work (#5696)
  perf(desktop): coalesce thread-activity localStorage writes (#5693)
  Batch observer-store publications per relay envelope (#5680)
  feat(buzz-acp): idle re-sleep for woken lazy pools (#5682)
  fix(desktop): preserve agent mention separator after send (#5623)
  fix(link-previews): proxy sent preview media (#5627)
  feat(deletion): add durable whole-community deletion (#4425)
  fix(desktop): preserve live channel timelines (#5662)
  Refine channel settings and profile panels (#5574)
  fix(deps): bump webbrowser to 1.2.4 for RUSTSEC-2026-0257 (#5659)
  feat(acp): deliver channel description in prompt [Context] (#4552)
  fix(desktop): launch Databricks OAuth from passive model discovery (#5607)
  chore(release): release Buzz Desktop version 0.5.10 (#5613)
  ...

Signed-off-by: Lazy Joe <dbd8c9941ba6dafebcef0abc015b65e75d52e7452f2ce483c9c3fd4d180f2504@buzz.block.builderlab.xyz>
thomaspblock added a commit that referenced this pull request Aug 13, 2026
The compact-preview geometry smoke test from #5629 stubs its image at the
raw relay origin (http://localhost:3000/media/*.png), but #5627 rewrites
sent snapshot media through the authenticated local media proxy
(http://127.0.0.1:54321 in the E2E mock bridge). The two changes raced:
each was green on its own branch, but once both were on main the image
request goes to the proxy origin, the stub never matches, naturalWidth
stays 0, and Desktop Smoke E2E (3) fails on every main and PR build.

Point the route stub at the mock proxy origin, matching the existing
'sent link preview media uses the authenticated proxy' test.

Co-authored-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
wesbillman pushed a commit that referenced this pull request Aug 13, 2026
…oxy (#5799)

**Category:** fix (CI)
**User Impact:** None — test-only change that unblocks `main` and every
open PR.

**Problem:** `main` has been red since #5629 landed on `45f4b91a3`:
`Desktop Smoke E2E (3)` fails `compact link preview image geometry
truncates long titles to one line` on every build (main run 31727837133,
and e.g. #5792, #5790). Two independently-green PRs raced: #5629 added
the test stubbing its preview image at the raw relay origin
(`http://localhost:3000/media/*.png`), while #5627 rewrites sent
snapshot media through the authenticated local media proxy
(`http://127.0.0.1:54321` in the E2E mock bridge). Merged together, the
image request goes to the proxy origin, the stub never matches, and
`naturalWidth` stays `0`.

**Solution:** Point the route stub at the mock proxy origin, matching
the existing `sent link preview media uses the authenticated proxy in
compact and rich cards` test in the same spec.

**Testing:** Reproduced the failure locally on `45f4b91a3`, then with
this fix: targeted test passes, and the full `messaging.spec.ts` smoke
suite passes 58/58.

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Co-authored-by: Wintermute <3f1797424fd9ad6653a83665c660517777cd7f8c228c0d5907f49e01537f3ca5@buzz.block.builderlab.xyz>
yjc801 added a commit to yjc801/buzz that referenced this pull request Aug 14, 2026
GitHub's mergeability check reports CONFLICTING (mergeStateStatus DIRTY,
PUT /pulls/61/update-branch fails 422) for this branch against main at
31d9b41, even at the exact SHAs GitHub itself reports. Local git
(merge-tree --write-tree, merge --no-commit, both -s recursive and -s ort,
checked against each of the two criss-cross merge-bases individually)
comes back 100% clean every time - including for
desktop/tests/e2e/messaging.spec.ts, the file GitHub's web UI shows a
conflict marker for around the block#5627 media-proxy route change.

This branch and main share two independent merge-bases (this branch's own
prior upstream-sync merge, plus main's separate absorption of overlapping
commits). Git's recursive/ort strategy resolves criss-cross histories by
computing a virtual merge base from the two real ones first; GitHub's
merge engine is known to handle multi-merge-base histories more naively
and can report a conflict where a virtual-base merge finds none. Landing
this merge commit directly (computed with real git, not GitHub's engine)
sidesteps the discrepancy: the branch head now already contains main, so
GitHub's own compare/merge check has nothing left to resolve.

Signed-off-by: Junchao Yan <yjc801@gmail.com>
yjc801 added a commit to yjc801/buzz that referenced this pull request Aug 14, 2026
* Make workflow run history authoritative in Desktop (block#5780)

## Summary

- persist stable workflow run `error_code` values separately from human
diagnostics
- expose NIP-98 authenticated, channel-authorized run history and
approval reads with stable keyset pagination
- connect Desktop to those authoritative reads and return the
relay-created run ID on trigger
- show truthful loading, failure, and pending-trace states, and do not
render approval actions from non-actionable stored hashes

## Validation

- pre-push `branch-skew`, `desktop-typecheck`, `desktop-test`,
`rust-tests`, `desktop-tauri-checks`, and `desktop-check` all passed on
`a097dbe5f`
- Desktop tests: 4,761 passed, 0 failed
- `cargo check -p buzz-relay`
- `git diff --check`

## Remaining gate

This does not claim a relay-backed Playwright workflow journey. The
browser relay bridge still routes workflow invokes through in-memory
handlers; that production-shaped acceptance gate remains follow-up work
before Workflows can leave preview.

---------

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Co-authored-by: Mongo <5c25403eab7271f9f94ddd4f2b270e8cac2c92e2c830c51877cca6ec974ffb3f@buzz.block.builderlab.xyz>
Co-authored-by: Princess Donut <68157ebd23b3897c1991015c3038658ea916200c67d3a54620b0754d1b92f6e0@buzz.block.builderlab.xyz>

* fix(desktop): route compact preview geometry fixture through media proxy (block#5799)

**Category:** fix (CI)
**User Impact:** None — test-only change that unblocks `main` and every
open PR.

**Problem:** `main` has been red since block#5629 landed on `45f4b91a3`:
`Desktop Smoke E2E (3)` fails `compact link preview image geometry
truncates long titles to one line` on every build (main run 31727837133,
and e.g. block#5792, block#5790). Two independently-green PRs raced: block#5629 added
the test stubbing its preview image at the raw relay origin
(`http://localhost:3000/media/*.png`), while block#5627 rewrites sent
snapshot media through the authenticated local media proxy
(`http://127.0.0.1:54321` in the E2E mock bridge). Merged together, the
image request goes to the proxy origin, the stub never matches, and
`naturalWidth` stays `0`.

**Solution:** Point the route stub at the mock proxy origin, matching
the existing `sent link preview media uses the authenticated proxy in
compact and rich cards` test in the same spec.

**Testing:** Reproduced the failure locally on `45f4b91a3`, then with
this fix: targeted test passes, and the full `messaging.spec.ts` smoke
suite passes 58/58.

Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Co-authored-by: Wintermute <3f1797424fd9ad6653a83665c660517777cd7f8c228c0d5907f49e01537f3ca5@buzz.block.builderlab.xyz>

* fix(desktop): enforce agent mention authorization at send boundaries (block#5681)

## Summary
- allow channel-member remote/headless agents only with current kind
`10100` directory evidence, while stale member identities remain hidden
- fail closed while managed/relay directories load, error, or
background-refetch across channel, forum, and cached autocomplete
surfaces
- revalidate agent mention authorization immediately before normal sends
and message-edit saves, including after deferred uploads
- in owner-only builds, fetch fresh authoritative profile ownership at
send time and deny missing, changed-owner, or unavailable proofs
- preserve human mention tags when agent authorization is revoked or
unknown

Supersedes block#5536 because its contributor-fork head cannot be updated by
maintainers.

## Validation
Exact head: `7278cdd5fbcee676c7b858ea098503c62eeeff0d`

- mandatory pre-push suites passed: desktop check/typecheck/tests, Rust
tests, mobile tests, desktop Tauri checks, branch-skew
- desktop unit tests: 4,732 passed
- focused edit/ownership regressions: 8 passed
- focused mention E2E: 5 passed (remote positive, stale-member negative,
directory error, pre-send revocation, mid-send revocation)
- file-size ratchet passed

One first focused E2E batch had a timing-only miss where the send click
did not emit; the isolated rerun passed. One separate pre-push attempt
hit the existing randomized passphrase separator test; the successful
exact-head push reran and passed the mandatory suite.

---------

Signed-off-by: JDiz00 <174381550+JDiz00@users.noreply.github.com>
Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: JDiz00 <174381550+JDiz00@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>

* feat(desktop): add Inbox message delete action (block#5779)

### What changed?

Inbox message action menus now show a standalone Delete action beside
Edit for manageable messages. Delete reuses the existing confirmation
and targets the message whose menu was opened, while the existing
empty-edit deletion path remains unchanged.

### Why?

Inbox users can delete a message directly without first entering edit
mode. Thread context can contain multiple messages, so the action must
preserve the active Inbox selection and delete only the chosen row.

### How is it tested?

Desktop checks, typechecking, builds, and test suites pass.

Added tests:

- [Inbox edit and delete E2E
coverage](https://github.com/block/buzz/tree/main/desktop/tests/e2e/inbox-edit.spec.ts)

Signed-off-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>

* fix(channels): return complete member rosters (block#5765)

## Summary

- return complete channel rosters instead of truncating at 1,000 members
- chunk `event_mentions` inserts inside one transaction so large kind
`39002` snapshots remain discoverable by every `p` tag
- add a targeted `buzz-admin reconcile-channels --channel <uuid>`
force-republish path for stale discovery snapshots
- cover a 1,501-member roster, 11,000-tag mention index, and kind
`39002` tag construction past member 1,000

## Why

The relay builds NIP-29 discovery and several authorization decisions
from `get_members()`, but that helper silently returned only the first
1,000 active members. Desktop then counted the truncated kind `39002`
event, while late members could be rejected by roster-scanning member
actions.

Removing the roster cap exposes PostgreSQL's 65,535 bind-parameter
ceiling in mention indexing, so the insert is chunked transactionally to
preserve all-or-nothing indexing.

The existing reconcilers only fill missing discovery events. The
targeted admin option bypasses the separately known 1,000-channel
reconciliation-list ceiling and replaces an existing channel snapshot
using the configured production relay key.

## Attribution

This supersedes and builds on block#3166 by @LordMelkor. Thank you for
identifying the roster boundary and contributing the original
complete-roster and mention-index patch. The production roster/query
changes and the two PostgreSQL regressions retain that work's shape;
this PR rebases it onto current `main`, adds relay coverage, and adds
the targeted repair operation requested for rollout.

## Validation

Exact pushed head: `24d02e4f3824150ed84913c9d230e675502e5b12`

- `cargo check -p buzz-db -p buzz-admin`
- `cargo test -p buzz-db
channel::tests::get_members_returns_full_roster_beyond_1000 -- --ignored
--exact --nocapture`
- `cargo test -p buzz-db
feed::tests::insert_mentions_indexes_rosters_past_bind_parameter_cap --
--ignored --exact --nocapture`
- `cargo test -p buzz-relay --lib
handlers::side_effects::tests::group_members_snapshot_keeps_members_past_one_thousand
-- --exact`
- `cargo run -q -p buzz-admin -- reconcile-channels --help`
- mandatory pre-push hook: branch-skew, desktop checks/typecheck/tests,
mobile tests, Rust tests, and desktop Tauri checks all passed on the
pushed head

## Rollout

1. Deploy the relay/backend build.
2. Run `buzz-admin reconcile-channels --channel <general-channel-uuid>`
with `BUZZ_RELAY_PRIVATE_KEY` configured.
3. Verify the replacement kind `39002` roster count matches the active
database membership count.

No schema migration or desktop release is required.

Fixes block#3156
Supersedes block#3166

---------

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>

* test: add deterministic desktop release smoke (block#5699)

## Summary

- add `just desktop-release-smoke`, a deterministic desktop
correctness/reachability smoke against an ephemeral real local relay
- preserve existing DM history when the first live DM enters a pageless
query window, the desktop-v0.5.10 disappearing-DM regression
- enforce foreground JS ordering: a frame and actionable sidebar input
must dispatch before mounted stale queries begin resume refetches, while
separately requiring the navigation to commit promptly
- seed a 10,000-event dense-second fixture and verify exact event-ID
reachability, SHA-256 identity, ordering, duplicate absence, bounded
mounted rows, and drained render work
- isolate Postgres per run, serialize the shared Redis DB, retain
phase/relay/Playwright diagnostics, and gate desktop release manifest
assembly on the smoke

This is deliberately **not a performance-regression gate**. CDP and
action timing fields are informational only. There is no
candidate/baseline comparison or threshold. A future performance lane
needs repeated equivalent fixtures, discrete interaction samples, and an
explicit comparator/noise policy.

The diagnostics record the fixture version, row count, wall-clock base
timestamp (`fixtureSecond`), expected event-ID hash, observed state, and
measurements. Because the created-at floor requires a current timestamp,
paired comparison remains disabled.

The release job runs on an isolated GitHub-hosted runner. The script
also guards automatic local runs with a Redis allocation lock. Its
remaining direct-PID cleanup and free-port selection race mean it should
not be repurposed onto a persistent concurrent shared runner without
first hardening process-group cleanup and port reservation.

### Related issue

N/A

### Testing

- `pnpm --dir desktop typecheck`
- focused real-local-relay release smoke passed after adversarial review
fixes
- identical DM witness passed current and failed `desktop-v0.5.10` with
the history-loss signature
- identical foreground witness bytes
(`2c1e97df04c9b8ca0304b66bbbe9bdb4d08924ad8ce0f68a9c490458fcc3aca8`)
failed `desktop-v0.5.10` structurally: the first resume fetch was marker
1, before first frame/sidebar dispatch at marker 8
- with PR block#5696 (`59f613c40`) merged, the witness showed focus at 951.3
ms, first frame at 951.6 ms, click dispatch at 952.1 ms, first resume
fetch at 968.9 ms, and route commit at 992.4 ms
- the gate therefore protects first paint and actionable input dispatch;
route commit is a bounded responsiveness witness, not a prerequisite for
resume work
- the corrected focused foreground scenario passed at
`6d9b5be40da58bbee92a856b04c3558946d0a950`; the prior merged-tree full
run passed DM retention and 10k reachability before exposing this
contract mismatch
- pre-push passed on exact pushed head
`6d9b5be40da58bbee92a856b04c3558946d0a950`, including desktop checks,
typecheck, desktop tests, Rust tests, mobile tests, and Tauri checks
- full 10,000-event scenario reached 10,000/10,000 exact IDs with
matching SHA-256, 199 continuation requests, and 95 mounted rows in
about 4.4 minutes
- reduced-row review run passed in 18.4 seconds

### Foreground witness boundary

The Chromium test is a deterministic JS policy gate. Headless Chromium
does not expose an honest blur/focus transition in this fixture, so the
test drives the production focus listener and `document.hasFocus()`
predicate together and records that simulation explicitly. It proves
refetch fan-out ordering, not AppKit activation, WKWebView paint, or an
activating physical click. A packaged macOS native lane is still
required before claiming the actual desktop activation experience is
certified.

---------

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>

* Polish glass Huddle tray behavior (block#5590)

## Summary

- inset the in-app Huddle tray with four rounded corners and even 8px
spacing when Glass background is enabled
- keep the popped-out Huddle dock full-width
- hide and suppress Glass background on Linux

## Why

The in-app tray reused the opaque backing needed by non-glass windows,
which covered the native vibrancy around it. Linux does not support this
window treatment.

## Testing

- `pnpm -C desktop build:e2e`
- focused Appearance and Huddle Playwright smoke tests
- pre-push desktop checks, typecheck, and 4,666 unit tests

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>

* Speed up initial direct messages (block#5658)

## Summary

- avoid blocking first-DM navigation on a full channel-list refresh
- publish the initial message through the acknowledged HTTP path instead
of waiting on a missing WebSocket acknowledgement

## Validation

- 4,715 desktop unit tests
- desktop typecheck and checks
- focused new-DM Playwright coverage

---------

Signed-off-by: kenny lopez <klopez4212@gmail.com>
Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz>

* Preserve member admission during send-time mention revalidation

getAgentMentionAdmission's lenient-member rule requires isMember and
compares against directoryAgentPubkeys, but revalidateAgentMentionPubkeys
called it without either — a channel-member agent with no kind:10100
directory record that the picker correctly admits was then denied by the
mandatory pre-send revalidation pass, silently dropping its mention tag
(no wake, no audience promotion, no Huddle enrollment) while the visible
@name stayed in the message text.

Thread channel-membership pubkeys through revalidateAgentMentionPubkeys
and useAgentMentionRevalidation, and derive directoryAgentPubkeys from the
freshly refetched relay directory so revalidation applies the same
admission rule the picker uses.

Reported-by: Alex <alex@buzz>
Signed-off-by: Junchao Yan <yjc801@gmail.com>

* Refetch channel roster during send-time mention revalidation

The prior fix passed the picker's cached membership set into revalidation
while the managed-agent and relay directories were freshly refetched. That
left a stale-membership window: if another admin removed a directory-less
agent after the picker/draft loaded, the cached member set still marked it
a member, so isLenientMember kept admitting it and the send emitted its
mention/wake tag for an agent no longer in the channel. The membership
query's 30s staleTime and user-scoped invalidation subscription don't fence
against another member's removal.

Refetch the channel roster in the same Promise.all as the managed/relay
directory refetches and derive membership from that fresh result. Fail
closed (deny) when the roster refetch errors or returns no data, matching
the existing fail-closed behavior for the other directory fetches.

Reported-by: Alex <alex@buzz>
Signed-off-by: Junchao Yan <yjc801@gmail.com>

* Only require fresh channel roster for channel-scoped mention admission

Round-2's fail-closed roster refetch ran unconditionally, so a new-DM
composer (MessageComposer with channelId=null, eligibilityScope
"managed-only", before onPrepareSendChannel creates the channel) had no
roster to fetch, failed closed, and stripped a valid managed-agent mention
before the DM was ever created.

Roster proof is only relevant to the lenient channel-member admission
branch. Fetch it only when eligibilityScope.type === "channel"; other
scopes use an empty member set and are admitted on the managed/relay
directory checks alone, same as before the roster refetch existed.

Reported-by: Alex <alex@buzz>
Signed-off-by: Junchao Yan <yjc801@gmail.com>

---------

Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Signed-off-by: Thomas Petersen <thomasp@squareup.com>
Signed-off-by: JDiz00 <174381550+JDiz00@users.noreply.github.com>
Signed-off-by: Tom Brow <tomb@block.xyz>
Signed-off-by: kenny lopez <klopez4212@gmail.com>
Signed-off-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Signed-off-by: Junchao Yan <yjc801@gmail.com>
Co-authored-by: Wes <wesbillman@users.noreply.github.com>
Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz>
Co-authored-by: Mongo <5c25403eab7271f9f94ddd4f2b270e8cac2c92e2c830c51877cca6ec974ffb3f@buzz.block.builderlab.xyz>
Co-authored-by: Princess Donut <68157ebd23b3897c1991015c3038658ea916200c67d3a54620b0754d1b92f6e0@buzz.block.builderlab.xyz>
Co-authored-by: thomaspblock <thomasp@squareup.com>
Co-authored-by: Wintermute <3f1797424fd9ad6653a83665c660517777cd7f8c228c0d5907f49e01537f3ca5@buzz.block.builderlab.xyz>
Co-authored-by: JDiz00 <174381550+JDiz00@users.noreply.github.com>
Co-authored-by: Tom Brow <tomb@block.xyz>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: klopez4212 <klopez4212@gmail.com>
Co-authored-by: Princess Donut <b238ea756dee4d98afa5883fc7f1de61eeabe65bf700e3a5a5a80db5e42e2c2b@buzz.block.builderlab.xyz>
Co-authored-by: Mongo <9cfd347903944d5b85aa6c93d2ab67381b978a92a31914bca69998968752a1d7@buzz.block.builderlab.xyz>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants